﻿using System.Windows.Media;
using System.Windows;

namespace LS.Screening.UI.Common
{
    /// <summary>
    /// DependencyObject扩展类
    /// </summary>
    public static class DependencyObjectExtensions
    {
        /// <summary>
        /// 查找子控件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="d"></param>
        /// <param name="filter"></param>
        /// <returns></returns>
        public static List<T> FindChildren<T>(this DependencyObject d, Func<T, bool> filter = null) where T : class
        {
            if (d == null) return null;
            var ret = new List<T>();
            var count = VisualTreeHelper.GetChildrenCount(d);
            for (int i = 0; i < count; i++)
            {
                var c = VisualTreeHelper.GetChild(d, i);
                if (c is T t)
                {
                    if (filter != null && filter.Invoke(t) || filter == null)
                    {
                        ret.Add(t);
                    }
                }
                else
                {
                    var temp = FindChildren<T>(c, filter);
                    if (temp.Count > 0) ret.AddRange(temp);
                }
            }
            return ret;
        }

        /// <summary>
        /// 查找子控件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="d"></param>
        /// <param name="filter"></param>
        /// <returns></returns>
        public static T FindFirstChildren<T>(this DependencyObject d, Func<T, bool> filter = null) where T : class
        {
            if (d == null) return null;
            var ret = new List<T>();
            var count = VisualTreeHelper.GetChildrenCount(d);
            for (int i = 0; i < count; i++)
            {
                var c = VisualTreeHelper.GetChild(d, i);
                if (c is T t)
                {
                    return t;
                }
                else
                {
                    var temp = FindFirstChildren<T>(c, filter);
                    if (temp != null) return temp;
                }
            }
            return null;
        }

        /// <summary>
        /// 根据类型，查找父节点
        /// </summary>
        /// <typeparam name="T">查找对象类型</typeparam>
        /// <param name="d">查找源点</param>
        /// <param name="filter">筛选条件</param>
        /// <returns>查找对象</returns>
        public static T FindParent<T>(this DependencyObject d, Func<T, Boolean> filter = null) where T : class
        {
            if (d == null)
                return null;

            var parent = LogicalTreeHelper.GetParent(d) ?? VisualTreeHelper.GetParent(d);

            while (parent != null)
            {
                if (parent is T t)
                {
                    if (filter == null)
                        return t;
                    else if (filter.Invoke(t))
                        return t;
                }
                parent = LogicalTreeHelper.GetParent(parent) ?? VisualTreeHelper.GetParent(parent);
            }
            return null;
        }
    }
}
